package com.ybkj.daijia.server.controller;

import com.ybkj.daijia.serverUtils.ExcelUtil;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.common.Pager;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.exception.NoPermissionException;
import com.ybkj.daijia.server.event.model.OperationLogEvent;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.DjInsurance;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.DjInsuranceService;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

/**
 * Created by shine on 15/9/8.
 */
@Controller
@RequestMapping(value = "insurances")
public class InsuranceController {

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${module.insurance.url}")
    private String insuranceBaseURL;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private DjInsuranceService djInsuranceService;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @RequestMapping(value = "create", method = RequestMethod.POST)
    public @ResponseBody
    Result create() {

        Company company = companyService.getMain();

        Result result = new Result();
        result.setSuccess(false);
        result.setMessage("失败");

        Principal principal = (Principal) SecurityUtils.getSubject().getPrincipal();

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(insuranceBaseURL);
        if (!insuranceBaseURL.endsWith("/")) {
            stringBuilder.append("/");
        }
        stringBuilder.append("api/v1/app");
        stringBuilder.append("?appKey={appKey}&name={name}&operator={operator}");

        Map<String, String> params = new HashMap<>();
        params.put("appKey", settingUtils.get().getSecKey());
        params.put("name", company.getAbbreviation());
        params.put("operator", principal.getUsername());//操作人

        try {
            ResponseEntity<String> responseEntity = restTemplate
                .postForEntity(stringBuilder.toString(), null, String.class, params);

            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                if (responseEntity.getStatusCode().compareTo(HttpStatus.CREATED) == 0) {
                    result.setSuccess(true);
                    result.setMessage("成功");

                    String detail = "【%s】已仔细阅读并且同意《平安代驾责任险条款》，并且开通了保险业务。";
                    OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
                    applicationEventMulticaster.multicastEvent(operationLogEvent); //发送事件通知,记录日志
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @RequestMapping("aggrement")
    public String noApp(Model model) {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(insuranceBaseURL);
        if (!insuranceBaseURL.endsWith("/")) {
            stringBuilder.append("/");
        }
        stringBuilder.append("api/v1/aggrements").append("?appKey={appKey}");

        Map<String, String> params = new HashMap<>();
        params.put("appKey", settingUtils.get().getSecKey());

        try {
            ResponseEntity<String> responseEntity = restTemplate
                .getForEntity(stringBuilder.toString(), String.class, params);

            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                JSONObject jsonObject = new JSONObject(responseEntity.getBody());
                model.addAttribute("aggrement", jsonObject.opt("data"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            model.addAttribute("aggrement", "");
        }

        return "insurance/noapp";
    }


    @RequestMapping(value = "details", method = RequestMethod.GET)
    public String details(Model model) throws Throwable {

        Subject subject = SecurityUtils.getSubject();

        if (subject.isPermitted("insurance")) {

            JSONObject app = queryInsuranceApp();
            if (null == app) {
                return "redirect:/insurances/aggrement";
            }

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(insuranceBaseURL);
            if (!insuranceBaseURL.endsWith("/")) {
                stringBuilder.append("/");
            }
            stringBuilder.append("api/v1/insurances/insuranceAppDetails");
            stringBuilder.append("?appKey={appKey}&page={page}&rows={rows}");

            Map<String, String> params = new HashMap<>();
            params.put("appKey", settingUtils.get().getSecKey());
            params.put("page", String.valueOf((Pager.getPage() + 1)));
            params.put("rows", String.valueOf(Pager.getLimit()));

            ResponseEntity<String> responseEntity = restTemplate
                .getForEntity(stringBuilder.toString(), String.class, params);

            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                if (responseEntity.hasBody()) {

                    JSONObject jsonObject = new JSONObject(responseEntity.getBody().toString());
                    JSONObject data = jsonObject.getJSONObject("data");

//	                JSONObject insuranceApp = data.getJSONObject("insuranceApp");
                    JSONObject datagrid = data.getJSONObject("insuranceAppDetails");

                    JSONArray jsonArray = datagrid.getJSONArray("rows");

                    List<JSONObject> list = new LinkedList<>();

                    if (null != jsonArray) {
                        for (int i = 0; i < jsonArray.length(); i++) {
                            list.add(jsonArray.getJSONObject(i));
                        }
                    }

                    Long total = datagrid.getLong("total");

                    model.addAttribute("app", app);
                    model.addAttribute("rows", list);
                    model.addAttribute("total", total);

                }
            }

            return "insurance/details";
        } else {
            throw new NoPermissionException();
        }
    }

    @RequestMapping(value = "list", method = RequestMethod.GET)
    public String list(Model model) throws Throwable {

        Subject subject = SecurityUtils.getSubject();

        if (subject.isPermitted("insurance")) {

            JSONObject app = queryInsuranceApp();
            if (null == app) {
                return "redirect:/insurances/aggrement";
            }

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(insuranceBaseURL);
            if (!insuranceBaseURL.endsWith("/")) {
                stringBuilder.append("/");
            }
            stringBuilder.append("api/v1/insurances")
                .append("?appKey={appKey}&page={page}&rows={rows}");

            Map<String, String> params = new HashMap<>();
            params.put("appKey", settingUtils.get().getSecKey());
            params.put("page", String.valueOf((Pager.getPage() + 1)));
            params.put("rows", String.valueOf(Pager.getLimit()));

            ResponseEntity<String> responseEntity = restTemplate
                .getForEntity(stringBuilder.toString(), String.class, params);

            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                if (responseEntity.hasBody()) {

                    JSONObject jsonObject = new JSONObject(responseEntity.getBody().toString());
                    JSONObject datagrid = jsonObject.getJSONObject("data");

                    JSONArray jsonArray = datagrid.getJSONArray("rows");

                    List<JSONObject> list = new LinkedList<>();

                    if (null != jsonArray) {
                        for (int i = 0; i < jsonArray.length(); i++) {
                            list.add(jsonArray.getJSONObject(i));
                        }
                    }

                    Long total = datagrid.getLong("total");

                    model.addAttribute("app", app);
                    model.addAttribute("rows", list);
                    model.addAttribute("total", total);

                }
            }

            return "insurance/list";
        } else {
            throw new NoPermissionException();
        }
    }

    @RequestMapping(value = "listinsurance", method = RequestMethod.GET)
    public ModelAndView listinsurance(
        @RequestParam(required = false, value = "type") String type,
        @RequestParam(required = false, value = "startTime") String startTime,
        @RequestParam(required = false, value = "endTime") String endTime) {

        Subject subject = SecurityUtils.getSubject();

        if (subject.isPermitted("insurance")) {
            ModelAndView mv = new ModelAndView();
            mv.setViewName("insurance/listinsurance");

            Date start = null;
            Date end = null;

            if (StringUtils.isNotBlank(startTime)) {
                try {
                    start = DateUtils.parseDate(startTime, "yyyy-MM-dd HH:mm");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }

            if (StringUtils.isNotBlank(endTime)) {
                try {
                    end = DateUtils.parseDate(endTime, "yyyy-MM-dd HH:mm");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }

            if (StringUtils.isBlank(type)) {
                type = null;
            }

            mv.addObject("page", djInsuranceService.queryByParam(type, start, end));
            mv.addObject("startTime", startTime);
            mv.addObject("endTime", endTime);
            mv.addObject("type", type);

            return mv;
        } else {
            throw new NoPermissionException();
        }

    }

    //导出
    @RequestMapping(value = "exportInsurance", method = RequestMethod.GET)
    public void exportOrder(
        @RequestParam(required = false, value = "type") String type,
        @RequestParam(required = false, value = "startTime") String startTime,
        @RequestParam(required = false, value = "endTime") String endTime,
        HttpServletRequest req, HttpServletResponse response) throws IOException {

        Subject subject = SecurityUtils.getSubject();
        if (subject.isPermitted("insurance")) {
            Date start = null;
            Date end = null;

            if (StringUtils.isNotBlank(startTime)) {
                try {
                    start = DateUtils.parseDate(startTime, "yyyy-MM-dd HH:mm");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }

            if (StringUtils.isNotBlank(endTime)) {
                try {
                    end = DateUtils.parseDate(endTime, "yyyy-MM-dd HH:mm");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }

            if (StringUtils.isBlank(type)) {
                type = null;
            }

            List<DjInsurance> djInsurances = djInsuranceService.listByParam(type, start, end);

            List<List<String>> rowlist = new ArrayList<List<String>>();
            String[] head = new String[4];
            head[0] = ("投保金额");
            head[1] = ("类型");
            head[2] = ("订单号");
            head[3] = ("时间");

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            for (DjInsurance dji : djInsurances) {
                List<String> celllist = new ArrayList<String>();

                celllist.add(dji.getMoney().toString());

                if (dji.getInsuranceType().compareTo(DjInsurance.InsuranceType.djx) == 0) {
                    celllist.add("代驾险");
                } else if (dji.getInsuranceType().compareTo(DjInsurance.InsuranceType.ywx) == 0) {
                    celllist.add("意外险");
                }

                celllist.add(dji.getOrderNo());
                celllist.add(sdf.format(dji.getCreated()));

                rowlist.add(celllist);

            }

            ExcelUtil.export(req, response, head, rowlist);
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "charge", method = RequestMethod.GET)
    public String chargeIndex(@RequestParam(value = "msg", required = false) String msg,
        Model model) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(insuranceBaseURL);
        if (!insuranceBaseURL.endsWith("/")) {
            stringBuilder.append("/");
        }
        stringBuilder.append("m/v1/notices");

        ResponseEntity<String> responseEntity = restTemplate
            .getForEntity(stringBuilder.toString(), String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            if (responseEntity.hasBody()) {
                JSONObject jsonObject = new JSONObject(responseEntity.getBody().toString());
                String data = jsonObject.getString("data");
                msg = data;
            }
        }
        model.addAttribute("msg", msg);
        model.addAttribute("appkey", settingUtils.get().getSecKey());
        return "insurance/charge";
    }


    @RequestMapping(value = "app")
    public void findApp(HttpServletResponse response) throws Exception {
        Properties prop = PropertiesLoaderUtils.loadAllProperties("config.properties");
        String daijia = prop.getProperty("function.daijia.open");
        if (Boolean.valueOf(daijia)) {
            Principal principal = (Principal) SecurityUtils.getSubject().getPrincipal();
            response.setContentType("text/plain");
            response.setCharacterEncoding("utf-8");
            PrintWriter out = response.getWriter();
            if (principal.isCompanyType()) {
                JSONObject jsonObject = queryInsuranceApp();

                if (null != jsonObject) {
                    out.println(jsonObject.toString());
                } else {
                    out.println("{}");
                }
            } else {
                out.println("{}");
            }
            out.flush();
            out.close();
        }
    }

    private JSONObject queryInsuranceApp() {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(insuranceBaseURL);
        if (!insuranceBaseURL.endsWith("/")) {
            stringBuilder.append("/");
        }
        stringBuilder.append("api/v1/app").append("?appKey={appKey}");

        Map<String, String> params = new HashMap<>();
        params.put("appKey", settingUtils.get().getSecKey());

        ResponseEntity<String> responseEntity = restTemplate
            .getForEntity(stringBuilder.toString(), String.class, params);

        HttpStatus httpStatus = responseEntity.getStatusCode();

        if (httpStatus.is2xxSuccessful()) {

            if (httpStatus.value() == 200) {
                JSONObject jsonObject = new JSONObject(responseEntity.getBody());
                JSONObject data = jsonObject.getJSONObject("data");
                return data;
            }
        }

        return null;

    }

}
